package com.baizhi.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.function.Function;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


public class MyBatisUtils {
	//2 创建sqlSessionFactory
	private static SqlSessionFactory factory ;
	static {
		//1 读取配置文件
		InputStream in;
		try {
			in = Resources.getResourceAsStream("mybatis-config.xml");
			System.out.println("in="+in);
			factory = new SqlSessionFactoryBuilder().build(in);
			System.out.println("factory="+factory);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	/*
	 * 抽取前3步，返回sqlSession
	 */
	public static SqlSession openSession() {
		//3 获取SqlSession
		SqlSession sqlSession = factory.openSession();
		return sqlSession;
	}
	
	/*
	 * 抽取最后1步，释放资源
	 */
	public static void close(SqlSession sqlSession) {
		if(sqlSession != null) {
			sqlSession.close();
		}
	}

	public static void main(String[] args) {
		System.out.println(openSession());
	}
	
	public static <S,T> T doQuery(Class<S> mapperClass,Function<S,T> executor) {
		SqlSession sqlSession = null;
		T target = null;
		try {
			sqlSession = MyBatisUtils.openSession();
			S mapper = sqlSession.getMapper(mapperClass);
			
			target = executor.apply(mapper);
			
			sqlSession.commit();
		}catch(Exception e) {
			sqlSession.rollback();
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}finally {
			MyBatisUtils.close(sqlSession);
		}
		return target;
	}
	
	public static <T> T doCallback(Function<SqlSession,T> callback) {
		SqlSession sqlSession = null;
		T target = null;
		try {
			sqlSession = MyBatisUtils.openSession();
			
			target = callback.apply(sqlSession);
			
			sqlSession.commit();
		}catch(Exception e) {
			sqlSession.rollback();
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}finally {
			MyBatisUtils.close(sqlSession);
		}
		return target;
	}
}
